/*	--- 外观 Facade --- 
Facade  n.  外观模式,门面

#	为【子系统】中的【一组接口】提供一个【一致的界面】。

【Facade模式】定义了一个【高层接口】，这个【接口】使得这一【子系统】更加容易【使用】。

=======================================================


【外观模式】，即Facade，是一个比较简单的模式。

它的基本思想如下：

	· 如果【客户端】要跟许多【子系统】打交道，那么【客户端】需要了解【各个子系统的接口】，比较麻烦。

	· 如果有一个【统一的“中介”】，让【客户端】只跟【中介】打交道，【中介】再去跟【各个子系统】打交道，对【客户端】来说就比较简单。


所以【Facade】就相当于搞了一个【中介】。

我们以【注册公司】为例，假设【注册公司】需要三步：

	1. 向【工商局】申请【公司营业执照】；
	2. 在【银行】开设【账户】；
	3. 在【税务局】开设【纳税号】。


以下是【三个系统的接口】： */

// 工商注册
public class AdminOfIndustry {
	public Company register(String name) {
		// ...
	}
}

// 银行开户
public class Blank {
	public String openAccount(String companyId) {
		// ... 
	}
}

// 纳税登记
public class Taxation {
	public String applyTaxCode(String companyId) {
		// ...
	}
}



/*
如果【子系统】比较【复杂】，并且【客户对流程】也不熟悉，那就把这些【流程】全部委托给【中介 Facade】： */
public class Facade {
	public Company openCompany(String name) {
		Company c = this.admin.register(name); 
			// admin n. 经营;管理
		String bankAccount = this.bank.openAccount(c.getId());
		c.setBankAccount(bankAccount);

		String taxCode = this.taxation.applyTaxCode(c.getId());
		c.setTaxCode(taxCode);

		return c; // return Company
	}
}



/*
这样，客户端只跟Facade打交道，一次完成公司注册的所有繁琐流程： */
Company c = facade.openCompany("Facade Software Ltd"));
	// Ltd abbr. 有限责任公司


/*
很多Web程序，内部有多个【子系统】提供【服务】，经常使用一个【统一的Facade入口】，例如一个【RestApiController】，使得【外部用户】调用的时候，只关心【Facade提供的接口】，不用管【内部】到底是哪个子系统处理的。


【更复杂的Web程序】，会有【多个Web服务】，这个时候，经常会使用一个【统一的网关入口】来自动转发到【不同的Web服务】，这种提供【统一入口的网关】就是【Gateway】，它本质上也是一个【Facade】，但可以附加一些【用户认证、限流限速】的额外服务。



==========================================================


#	练习

使用【Facade模式】实现一个【注册公司】的【“中介”服务】。 */






/*====================================================


#	----- 外观 の 小结 -----


1. 【Facade模式】是为了给【客户端】提供一个【统一入口】，并【对外】屏蔽【内部子系统的调用细节】。







*/






